<template>
    <div>
        <div class="button">
            <el-button v-limit="'添加'" type="primary" :icon="Plus" @click="addForm">添加</el-button>
        </div>
        <div class="table">
            <tableLayout :table-data="state.tableData" :data="state.data" :loading="state.loading" @operationChange="operationChange"></tableLayout>
        </div>
        <el-dialog v-model="state.dialogFormVisible" width="30%" @close="menuCancel" @open="opendialog(form)" @closed="closedorgan">
            <el-form ref="form" :model="state.form" :rules="state.rules" label-width="80px">
                <el-form-item label="上级菜单" prop="parentId">
                    <el-tree-select
                        v-model="state.form.parentId"
                        style="width: 100%"
                        :data="selectData"
                        :props="defaultProps"
                        check-strictly
                        :render-after-expand="false"
                        placeholder="请选择"
                        node-key="id"
                        @node-click="nodeClick"
                    ></el-tree-select>
                </el-form-item>
                <el-form-item label="菜单名称" prop="title">
                    <el-input v-model="state.form.title" placeholder="输入菜单名称" />
                </el-form-item>
                <el-form-item label="类型" prop="type">
                    <el-select v-model="state.form.type" style="width: 100%" placeholder="请选择">
                        <el-option v-for="item in state.typeOptions" :key="item.value" :label="item.label" :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="权限" prop="authority">
                    <el-select v-model="state.form.authority" style="width: 100%" placeholder="请选择">
                        <el-option v-for="item in state.authorityOptions" :key="item.value" :label="item.label" :value="item.value" />
                    </el-select>
                </el-form-item>
                <el-form-item label="是否隐藏" prop="isHide">
                    <el-radio-group v-model="state.form.isHide">
                        <el-radio :label="true">是</el-radio>
                        <el-radio :label="false">否</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="菜单路径" prop="path">
                    <el-input v-model="state.form.path" placeholder="输入菜单路径" @blur="setUrl" />
                </el-form-item>
                <el-form-item label="url" prop="name">
                    <el-input v-model="state.form.name" placeholder="输入url" />
                </el-form-item>
                <el-form-item label="排序号" prop="sortNumber">
                    <el-input v-model.number="state.form.sortNumber" type="text" placeholder="输入排序号" />
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="menuCancel">取消</el-button>
                    <el-button type="primary" @click="submit(form)">保存</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<script lang="ts" setup>
import { reactive, onMounted, ref, nextTick } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import API from '@/api';
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
import { useRouteStore } from '@/store';

import tableLayout from '@/dynamicCustom/components/tableLayout.vue';

const form = ref<FormInstance>();
const routeStore = useRouteStore();

interface type {
    value: string;
    label: string;
}

interface formtype {
    title?: string;
    parentId?: string;
    type?: string;
    isHide?: boolean;
    path?: string;
    name?: string;
    component?: string;
    authority?: string;
    singleLayout?: string;
    sortNumber?: number | null;
}

interface dataType {
    tableData: any[];
    loading: boolean;
    typeOptions: type[];
    data: any[];
    title: string;
    form: formtype;
    rules: object;
    dialogFormVisible: boolean;
    authorityOptions: any[];
}
const state: dataType = reactive({
    tableData: [],
    loading: false,
    typeOptions: [
        {
            value: 'directory',
            label: '页面'
        },
        {
            value: 'menu',
            label: '目录'
        }
    ],
    data: [
        { label: '菜单名称', prop: 'title' },
        { label: 'url', prop: 'url' },
        { label: '路径', prop: 'path' },
        { label: '排序', prop: 'sortNumber' },
        { label: '创建时间', prop: 'createTime' },
        {
            label: '操作',
            slotName: 'operation',
            operation: [
                {
                    label: '修改',
                    types: 'primary',
                    onClick: 'reviseMenu'
                },
                {
                    label: '删除',
                    types: 'primary',
                    onClick: 'deleteMenu'
                }
            ]
        }
    ],
    title: '添加菜单',
    form: {
        title: '',
        parentId: '',
        type: '',
        isHide: false,
        path: '',
        sortNumber: null,
        name: '',
        component: '',
        authority: ''
    },
    rules: {
        title: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
        type: [{ required: true, message: '请选择类型', trigger: 'change' }],
        path: [{ required: true, message: '请输入菜单路径', trigger: 'blur' }],
        name: [{ required: true, message: '请输入url', trigger: 'blur' }],
        sortNumber: [
            { required: true, message: '请输入排序号' },
            { type: 'number', message: '排序号必须是数字' }
        ]
    },
    dialogFormVisible: false,
    authorityOptions: []
});

// 给url赋值
const setUrl = (e: any) => {
    let path = e.target.value;
    path = path.replaceAll('/', '_');
    path = path.slice(1);
    state.form.name = path;
};

// 上级菜单的数据
const selectData = ref<any[]>();

const defaultProps = {
    children: 'children',
    label: 'title'
};

// 初始化
const getMenu = async () => {
    try {
        state.loading = false;
        const resp = await API.menu_tree({ method: 'GET' });
        state.tableData = resp;
        const menu = [{ title: '顶部菜单', id: -1 }];
        const list = [...menu, ...resp];
        selectData.value = list;
    } catch (err) {
        state.loading = false;
    }
};
// 初始化权限选项
const getPageUrlList = async () => {
    try {
        const resp = await API.menu_pageUrlList({ method: 'GET' });
        state.authorityOptions = resp.map((res: any) => {
            res.label = res.authorityName;
            res.value = res.authority;
            return res;
        });
    } catch (err) {}
};
// 当上级菜单选择时
const nodeClick = (val: object) => {
    console.log(val, state.form.parentId, 'state.form.parentId');
};

// 删除
const deleteMenu = (id: string) => {
    ElMessageBox.confirm('确认删除', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
    })
        .then(async () => {
            try {
                const res = await API.admin_menu({ urlVal: id, method: 'DELETE' });
                ElMessage.success('删除成功');
                getreset();
            } catch (err) {}
        })
        .catch(() => {
            ElMessage({
                type: 'info',
                message: '已取消删除'
            });
        });
};
// 修改按钮
const reviseMenu = (row: any) => {
    state.title = '修改菜单';
    if (!state.authorityOptions.length) {
        getPageUrlList();
    }
    state.form = row;
    if (row.parentId == '-1') {
        state.form.parentId = '';
    }
    if (row.component == 'self') {
        state.form.type = 'directory';
    } else {
        state.form.type = 'menu';
    }
    state.form.name = row.url;
    state.dialogFormVisible = true;
};

// 表格按钮回调
const operationChange = (data: any) => {
    const a: any = {
        deleteMenu: () => deleteMenu(data.row.id),
        reviseMenu: () => reviseMenu(data.row)
    };
    a[data.eventName]();
};

// 添加按钮
const addForm = () => {
    state.dialogFormVisible = true;
};

// 修改列表数据后的回调
const getreset = () => {
    state.dialogFormVisible = false;
    state.loading = true;
    getMenu();
    routeStore.initAuthRoute();
};

// 关闭弹框
const menuCancel = () => {
    state.dialogFormVisible = false;
};

// 关闭弹框的回调
const closedorgan = () => {
    state.form = {
        title: '',
        parentId: '',
        type: '',
        isHide: false,
        path: '',
        sortNumber: null,
        name: '',
        component: '',
        authority: ''
    };
};

// 打开添加弹框时
const opendialog = (form: FormInstance | undefined) => {
    if (!form) return;
    nextTick(() => {
        form.clearValidate();
    });
};

const submit = (form: FormInstance | undefined) => {
    if (!form) return;
    form.validate(async valid => {
        if (valid) {
            if (state.form.parentId === '') {
                state.form.parentId = '-1';
            }
            // 选了顶部菜单及类型为页面的时候
            if (state.form.parentId === '-1' && state.form.type === 'directory') {
                state.form.component = 'self';
                state.form.singleLayout = 'basic';
                state.form.parentId = '';
            }
            // 选了顶部菜单及类型为目录的时候
            if (state.form.parentId === '-1' && state.form.type === 'menu') {
                state.form.component = 'basic';
                state.form.parentId = '';
            }
            // 选了菜单及类型为也页面的时候
            if (state.form.parentId !== '-1' && state.form.type === 'directory') {
                state.form.component = 'self';
            }
            // 选了菜单及类型为也目录的时候
            if (state.form.parentId !== '-1' && state.form.type === 'menu') {
                state.form.component = 'multi';
            }
            const apiName = state.form.id ? API.menu_update : API.menu_add;
            const Method = state.form.id ? 'PUT' : 'POST';
            const data = state.form.id ? { id: state.form.id, ...state.form } : { ...state.form };
            try {
                const resp = await apiName({ data, method: Method });
                ElMessage.success('操作成功');
                getreset();
            } catch (error) {
                state.dialogFormVisible = false;
            }
        }
    });
};

onMounted(() => {
    state.loading = true;
    getMenu();
    getPageUrlList();
});
</script>
<style lang="scss" scoped>
.button {
    margin: 15px;
}
.table {
    height: 80%;
}
</style>
